// gcc -o test_sub_worker_plus test_sub_worker_plus.c
#define MAX_LEN_OF_COMMEND 255

#define RELABLE_SYSCALL_NUM 4294967290
#define DOWNGRADE_SYSCALL_NUM 4294967288

#include <sys/syscall.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<string.h>


int opt_read(const char * filename){
    //char filename[256];
    FILE *file;
    // 尝试打开文件
    file = fopen(filename, "r"); // 以只读模式打开文件
    if (file == NULL) {
        // 如果文件打开失败，打印错误信息并退出程序
        perror("文件打开失败");
        return 0;
    }
    // 读取并打印文件内容
    char ch;
    while ((ch = fgetc(file)) != EOF) { // 读取文件直到文件末尾
        putchar(ch); // 打印字符
    }
    // 关闭文件
    fclose(file);
    printf("文件内容已打印完毕。\n");
    return 1;
}

int opt_write(const char * filename, const char * write_what){
    //char filename[256];
    //char write_what[256];
    FILE *file;
    // 尝试打开文件
    file = fopen(filename, "a"); // 以只读模式打开文件
    if (file == NULL) {
        // 如果文件打开失败，打印错误信息并退出程序
        printf("文件打开失败\n");
        return EXIT_FAILURE;
    }
    // 写入文件
    if(fputs(write_what, file) == EOF){
        printf("向 %s 写入失败。\n", filename);
        return 0;
    }
    printf("向 %s 写入 %s 完毕。\n", filename, write_what);

    // 关闭文件
    fclose(file);

    return 1;
}

int opt_relable(int need_change_class_id, _Bool is_add, int op_what_id){
    int tmp = is_add;
    syscall(SYS_write, RELABLE_SYSCALL_NUM, need_change_class_id, tmp, op_what_id);
    printf("已提交 relabel 申请\n");

    return 1;
}

int opt_downgrade(int need_change_class_id, int add_what_id){
    syscall(SYS_write, DOWNGRADE_SYSCALL_NUM, need_change_class_id, add_what_id);
    printf("已提交 downgrade 申请\n");

    return 1;
}

int opt_create_file(const char * create_what){
    FILE *fp;
	fp = fopen(create_what,"w+"); // 创建名为test.c文件,"w+"该文件可读可写
	if(fp == NULL){
        printf("创建失败\n");
        return 0;
	}
    fprintf(fp,"%s","Hello \n");
    printf("创建成功\n");


	return 1;
}

int opt_remove_file(const char * remove_what){
    if(remove(remove_what) == 0) {
        printf("文件删除成功\n");
    } else {
        printf("删除文件失败");
    }
    return 0;
}

int opt_creat_fifo(const char * fifo_name){
    // 创建并写入命名管道
    if (mkfifo(fifo_name, 0666) == -1) {
        printf("opt_creat_fifo 失败\n");
        return 0;
    }
    printf("opt_creat_fifo 成功\n");
    return 1;
}

int opt_write_fifo(const char * fifo_name, const char * write_what){
    int write_fd = open(fifo_name, O_WRONLY);
    if (write_fd == -1) {
        printf("opt_write_fifo 失败\n");
        return 0;

    }
    write(write_fd, write_what, strlen(write_what));
    printf("向FIFO %s 写入 %s 成功\n", fifo_name, write_what);

    close(write_fd);
    return 1;
}

int opt_read_fifo(const char * fifo_name){
    // 读取命名管道
    int read_fd = open(fifo_name, O_RDONLY);
    if (read_fd == -1) {
        printf("88");
        return 0;
    }
    char read_buf[128];
    read(read_fd, read_buf, sizeof(read_buf) - 1);
    read_buf[sizeof(read_buf) - 1] = '\0'; // 确保字符串以空字符结尾
    printf("Read from FIFO: %s\n", read_buf);
    close(read_fd);
    return 1;

}

int do_one_line(const char *line_contents){
    char *commend_type = malloc(60);
    char *tmp_str = malloc(MAX_LEN_OF_COMMEND);
    char *tmp_str1 = malloc(MAX_LEN_OF_COMMEND);
    int opn1, opn2;

    if (line_contents[0]=='#')
        return 1;
    // printf(" > %s \n", line_contents);
    sscanf(line_contents, "%s", commend_type);

    if (strcmp(commend_type, "new") == 0){
        sscanf(line_contents, "new %s", tmp_str);
        // printf("创建文件: %s\n", tmp_str);
        opt_create_file(tmp_str);
    }
    else if (strcmp(commend_type, "remove") == 0){
        // printf("删除文件: %s\n", tmp_str);
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_remove_file(tmp_str);
    }
    else if (strcmp(commend_type, "read") == 0){
        // printf("读文件: %s\n", tmp_str);
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_read(tmp_str);
    }
    else if (strcmp(commend_type, "write") == 0){
        sscanf(line_contents, "%*s %s %s", tmp_str, tmp_str1);
        opt_write(tmp_str, tmp_str1);
    }
    else if (strcmp(commend_type, "downgrade") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt_downgrade(opn1, opn2);
        // printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "relabe_add") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt_relable(opn1, 1, opn2);
        //printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "relabe_remove") == 0){
        sscanf(line_contents, "%*s %d %d", &opn1, &opn2);
        opt_relable(opn1, 0, opn2);
        // printf("执行完成，但不知道是否成功，可通过查看访问控制日志来确认执行结果\n");
    }
    else if (strcmp(commend_type, "fifo_create") == 0){
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_creat_fifo(tmp_str);
    }
    else if (strcmp(commend_type, "fifo_write") == 0){
        sscanf(line_contents, "%*s %s %s", tmp_str, tmp_str1);
        opt_write_fifo(tmp_str, tmp_str1);
    }
    else if (strcmp(commend_type, "fifo_read") == 0){
        sscanf(line_contents, "%*s %s", tmp_str);
        opt_read_fifo(tmp_str);
    }
    else if (strcmp(commend_type, "exit") == 0){
        exit(EXIT_SUCCESS);
    }
    return 1;
}

int main(int argc, char *argv[]) {
    const char *id = "0";
    if (argc == 2)
        id = argv[1];
        char str[10];

        sprintf(str, "worker_%s", id);
        strcpy(argv[0], str);

    printf("Hello, I'm %s \n", id);
    fflush(stdout);

    char *buffer = malloc(MAX_LEN_OF_COMMEND);
    for(int i = 0;i<100;i++){
        if (fgets(buffer, MAX_LEN_OF_COMMEND,  stdin) == NULL) {
            perror("gets");
            return 1;
        }
        // printf("%s",buffer);
        int ans = do_one_line(buffer);
        // printf("%d\n",ans);
        fflush(stdout);
        fflush(stdout);

    }
    printf("Goodbye, I'm %s\n", id);
    exit(EXIT_SUCCESS);
}